home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / games / ted5.zip / LIB.C < prev    next >
C/C++ Source or Header  |  1993-02-04  |  19KB  |  1,012 lines

  1. #include "ted5.h"
  2. #pragma hdrstop
  3.  
  4. extern char far TEDCHAR,far VGAPAL;
  5.  
  6. void Quit(char *string);
  7. void drawchar(int x,int y,int chr);
  8. void centerwindow (int width, int height);
  9.  
  10. int win_xl,win_yl,win_xh,win_yh;
  11. int screencenterx = 19,screencentery = 11;
  12. unsigned char keydown[256];
  13. unsigned leftedge,yshift,xormask,MouseStatus,sx,sy;
  14. void interrupt (*oldint9) ()=NULL;
  15. enum {false,true} boolean;
  16. memptr CGAfont,VGAfont;
  17. unsigned doubled[256];
  18. //
  19. // Special vars to handle EGA3 mouse mode
  20. //
  21. int EGA3mx,EGA3my;
  22.  
  23.  
  24. ////////////////////////////////////////////////////////////////////
  25. //
  26. // Return a file's length
  27. //
  28. ////////////////////////////////////////////////////////////////////
  29. long filelen(char *filename)
  30. {
  31.  long size;
  32.  int handle;
  33.  
  34.  if ((handle=open(filename,O_BINARY))==-1)
  35.    return 0;
  36.  
  37.  size=filelength(handle);
  38.  close(handle);
  39.  return size;
  40. }
  41.  
  42. ////////////////////////////////////////////////////////////////////
  43. //
  44. // WaitVBL
  45. //
  46. ////////////////////////////////////////////////////////////////////
  47. void WaitVBL(int times)
  48. {
  49. asm    mov    cx,times
  50. asm    mov    dx,crtcaddr
  51. asm    add    dx,6
  52.  
  53. waitvbl1:
  54. asm    in    al,dx
  55. asm    test    al,00001000b    //;look for vbl
  56. asm    jnz    waitvbl1
  57.  
  58. waitvbl2:
  59. asm    in    al,dx
  60. asm    test    al,00001000b    //;look for vbl
  61. asm    jz    waitvbl2
  62.  
  63. asm    loop    waitvbl1
  64. }
  65.  
  66.  
  67. ////////////////////////////////////////////////////////////////////
  68. //
  69. // Int9ISR
  70. // Called for every keypress.  Keeps track of which keys are down, and passes
  71. // the key on to DOS after clearing the dos buffer (max 1 char in buffer).
  72. //
  73. ////////////////////////////////////////////////////////////////////
  74. void interrupt Int9ISR ()
  75. {
  76.  int key = inportb (0x60);        /* get the key pressed */
  77.  
  78.  if (key>127)
  79.    keydown [key-128] = false;        /* break scan code */
  80.  else
  81.  {
  82.    keydown [key] = true;        /* make scan code */
  83.    poke (0x40,0x1c,peek(0x40,0x1a));    /* clear the bios key buffer */
  84.  }
  85. asm {
  86.    push ax
  87.    push    bx
  88.    push    cx
  89.    push    dx
  90.    push    si
  91.    push    di
  92.    push    bp
  93.  }
  94.  oldint9 ();                /* give it to DOS */
  95. asm {
  96.    pop    bp
  97.    pop  di
  98.    pop    si
  99.    pop    dx
  100.    pop    cx
  101.    pop    bx
  102.    pop    ax
  103.  }
  104.  outport (0x20,0x20);            /* tell the int manager we got it */
  105. }
  106.  
  107.  
  108. ////////////////////////////////////////////////////////////////////
  109. //
  110. // SetupKBD
  111. // Clears the keydown array and installs the INT 9 ISR if it isn't already
  112. // hooked up.
  113. //
  114. ////////////////////////////////////////////////////////////////////
  115. void SetupKBD ()
  116. {
  117.  void far *vect = getvect (9);
  118.  int i;
  119.  
  120.  for (i=0;i<128;i++)            /* clear our key down table */
  121.    keydown[i]= false;
  122.  
  123.  poke (0x40,0x1c,peek(0x40,0x1a));    /* clear the bios key buffer */
  124.  
  125.  if ( &Int9ISR != vect )         /* is our handler allready set up? */
  126.  {
  127.    oldint9 = vect;
  128.    setvect (9,Int9ISR);
  129.  }
  130. }
  131.  
  132.  
  133. ////////////////////////////////////////////////////////////////////
  134. //
  135. // ShutdownKBD
  136. // Sets the int 9 vector back to oldint 9
  137. //
  138. ////////////////////////////////////////////////////////////////////
  139. void ShutdownKBD ()
  140. {
  141.  if (oldint9 != NULL)
  142.    setvect (9,oldint9);
  143. }
  144.  
  145.  
  146. ////////////////////////////////////////////////////////////////////
  147. //
  148. // clearkeys
  149. // Clears out the bios buffer and zeros out the keydown array
  150. //
  151. ////////////////////////////////////////////////////////////////////
  152. void clearkeys (void)
  153. {
  154.   int i;
  155.   while (bioskey (1))
  156.     bioskey(0);
  157.  
  158.   for (i=0;i<128;i++)
  159.     keydown [i]=0;
  160. }
  161.  
  162.  
  163. ////////////////////////////////////////////////////////////////////
  164. //
  165. // Mouse Routines
  166. //
  167. ////////////////////////////////////////////////////////////////////
  168. int MouseInit(void)
  169. {
  170.  union REGS regs;
  171.  unsigned char far *vector;
  172.  
  173.  if ((vector=MK_FP(peek(0,0x33*4+2),peek(0,0x33*4)))==NULL) return 0;
  174.  
  175.  if (*vector == 207)
  176.    return MouseStatus = 0;
  177.  
  178.  _AX=0;
  179.  geninterrupt(0x33);
  180.  EGA3mx=800/2;
  181.  EGA3my=600/2;
  182.  
  183.  //
  184.  // Set CGA mouse cursor (normal one sucks)
  185.  //
  186.  if (videomode==CGA)
  187.    {
  188.     static unsigned CGAcursor[]=
  189.       {
  190.        0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03,
  191.        0xff03,0xffff,0xffff,0xffff,0xffff,0xffff,
  192.  
  193.        0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c,
  194.        0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000
  195.       };
  196.  
  197.     _BX=0;
  198.     _CX=0;
  199.     _DX=FP_OFF(CGAcursor);
  200.     _ES=_DS;
  201.     _AX=9;
  202.     geninterrupt(0x33);
  203.    }
  204.  
  205.  return MouseStatus = 1;
  206. }
  207.  
  208.  
  209. void MouseOrigin(int x,int y)
  210. {
  211.  if (!MouseStatus) return;
  212.  
  213.  _CX=x;
  214.  _DX=y;
  215.  _AX=4;
  216.  geninterrupt(0x33);
  217. }
  218.  
  219.  
  220. void MouseLimits(int xmin,int xmax,int ymin,int ymax)
  221. {
  222.  if (!MouseStatus) return;
  223.  
  224.  _CX=xmin;
  225.  _DX=xmax;
  226.  _AX=7;
  227.  geninterrupt(0x33);
  228.  _CX=ymin;
  229.  _DX=ymax;
  230.  _AX=8;
  231.  geninterrupt(0x33);
  232. }
  233.  
  234.  
  235. void MouseHide(void)
  236. {
  237.  if (!MouseStatus) return;
  238.  
  239.  _AX=2;
  240.  geninterrupt(0x33);
  241. }
  242.  
  243.  
  244.  
  245. void MouseShow(void)
  246. {
  247.  if (!MouseStatus) return;
  248.  
  249.  _AX=1;
  250.  geninterrupt(0x33);
  251. }
  252.  
  253.  
  254.  
  255. int MouseButton(void)
  256. {
  257.  union REGS regs;
  258.  
  259.  if (!MouseStatus) return 0;
  260.  
  261.  regs.x.ax=3;
  262.  int86(0x33,®s,®s);
  263.  return(regs.x.bx);
  264. }
  265.  
  266.  
  267.  
  268. void MouseCoords(int *x,int *y)
  269. {
  270.  union REGS regs;
  271.  
  272.  if (!MouseStatus)
  273.    return;
  274.  
  275.  regs.x.ax=3;
  276.  int86(0x33,®s,®s);
  277.  *x=regs.x.cx;
  278.  *y=regs.x.dx;
  279.  
  280.  *x/=2;
  281.  if (videomode==EGA2)
  282.    *x*=2;
  283. }
  284.  
  285. /////////////////////////
  286. //
  287. // print
  288. // Prints a string at sx,sy.  No clipping!!!
  289. //
  290. /////////////////////////
  291.  
  292. void print (const char *str)
  293. {
  294.   char ch;
  295.  
  296.   while ((ch=*str++) != 0)
  297.     if (ch == '\n')
  298.     {
  299.       sy++;
  300.       sx=leftedge;
  301.     }
  302.     else if (ch == '\r')
  303.       sx=leftedge;
  304.     else
  305.       drawchar (sx++,sy,ch);
  306. }
  307. void fprint (const char huge *str)
  308. {
  309.   char ch;
  310.  
  311.   while ((ch=*str++) != 0)
  312.     if (ch == '\n')
  313.     {
  314.       sy++;
  315.       sx=leftedge;
  316.     }
  317.     else if (ch == '\r')
  318.       sx=leftedge;
  319.     else
  320.       drawchar (sx++,sy,ch);
  321. }
  322.  
  323. ////////////////////////////////////////////////////////////////////
  324. //
  325. // print hex byte
  326. //
  327. ////////////////////////////////////////////////////////////////////
  328. void printhexb(unsigned char value)
  329. {
  330.  int loop;
  331.  char hexstr[16]="0123456789ABCDEF",str[2]="";
  332.  
  333.  for (loop=0;loop<2;loop++)
  334.    {
  335.     str[0]=hexstr[(value>>(1-loop)*4)&15];
  336.     print(str);
  337.    }
  338. }
  339.  
  340. ////////////////////////////////////////////////////////////////////
  341. //
  342. // print hex
  343. //
  344. ////////////////////////////////////////////////////////////////////
  345. void printhex(unsigned value)
  346. {
  347.  print("$");
  348.  printhexb(value>>8);
  349.  printhexb(value&0xff);
  350. }
  351.  
  352.  
  353. ////////////////////////////////////////////////////////////////////
  354. //
  355. // print int
  356. //
  357. ////////////////////////////////////////////////////////////////////
  358. void printint(unsigned value)
  359. {
  360.  char temp[10];
  361.  
  362.  ultoa((unsigned long)value,temp,10);
  363.  print(temp);
  364. }
  365.  
  366.  
  367. ////////////////////////////////////////////////////////////////////
  368. //
  369. // print bin
  370. //
  371. ////////////////////////////////////////////////////////////////////
  372. void printbin(unsigned value)
  373. {
  374.  int loop;
  375.  
  376.  print("%");
  377.  for (loop=0;loop<16;loop++)
  378.     if ((value>>15-loop)&1) print("1"); else print("0");
  379. }
  380.  
  381.  
  382. ////////////////////////////////////////////////////////////////////
  383. //
  384. // input unsigned
  385. //
  386. ////////////////////////////////////////////////////////////////////
  387. unsigned inputint(int numchars)
  388. {
  389.  char string[18]="",digit,hexstr[16]="0123456789ABCDEF";
  390.  unsigned value,loop,loop1;
  391.  
  392.  if (!input(string,numchars))
  393.    return ESCOUT;
  394.  
  395.  if (string[0]=='$')
  396.    {
  397.     int digits;
  398.  
  399.     digits=strlen(string)-2;
  400.     if (digits<0) return 0;
  401.  
  402.     for (value=0,loop1=0;loop1<=digits;loop1++)
  403.       {
  404.        digit=toupper(string[loop1+1]);
  405.        for (loop=0;loop<16;loop++)
  406.       if (digit==hexstr[loop])
  407.         {
  408.          value|=(loop<<(digits-loop1)*4);
  409.          break;
  410.         }
  411.       }
  412.    }
  413.  else if (string[0]=='%')
  414.    {
  415.     int digits;
  416.  
  417.     digits=strlen(string)-2;
  418.     if (digits<0) return 0;
  419.  
  420.     for (value=0,loop1=0;loop1<=digits;loop1++)
  421.       {
  422.        if (string[loop1+1]<'0' || string[loop1+1]>'1') return 0;
  423.        value|=(string[loop1+1]-'0')<<(digits-loop1);
  424.       }
  425.    }
  426.  else value=atoi(string);
  427.  return value;
  428. }
  429.  
  430.  
  431. ////////////////////////////////////////////////////////////////////
  432. //
  433. // line input routine
  434. //
  435. ////////////////////////////////////////////////////////////////////
  436. int input(char *string,int max)
  437. {
  438.  char key;
  439.  int count=0,loop;
  440.  
  441.  do {
  442.      key=get()&0xff;
  443.      if ((key==127 || key==8)&&count>0)
  444.        {
  445.     count--;
  446.     drawchar(sx,sy,' ');
  447.     sx--;
  448.        }
  449.  
  450.      if (key>=' ' && key<='z' && count<max)
  451.        {
  452.     *(string+count++)=key;
  453.     drawchar(sx++,sy,key);
  454.        }
  455.  
  456.     } while (key!=27 && key!=13);
  457.  
  458.  for (loop=count;loop<max;loop++) *(string+loop)=0;
  459.  
  460.  while(keydown[1]);    // don't let ESC repeat
  461.  
  462.  if (key==13)
  463.    {
  464.     while(keydown[0x1c]);
  465.     return 1;
  466.    }
  467.  return 0;
  468. }
  469.  
  470. void bar (int xl, int yl, int xh, int yh, int ch)
  471. {
  472.   int x,y;
  473.  
  474.   for (y=yl;y<=yh;y++)
  475.     for (x=xl;x<=xh;x++)
  476.       drawchar (x,y,ch);
  477. }
  478.  
  479. /////////////////////////
  480. //
  481. // get
  482. // Flash a cursor at sx,sy and waits for a user bioskey
  483. //
  484. /////////////////////////
  485.  
  486. int get (void)
  487. {
  488.  int cycle,key;
  489.  
  490.  do
  491.  {
  492.    cycle = 9;
  493.    while (!(key = bioskey(1)) && cycle<11)
  494.    {
  495.      drawchar (sx,sy,cycle++);
  496.      WaitVBL (5);
  497.    }
  498.  } while (key == 0);
  499.  drawchar (sx,sy,' ');
  500.  return bioskey(0);        // take it out of the buffer
  501. }
  502.  
  503.  
  504. ////////////////////////////////////////////////////////////////////
  505. //
  506. // drawchar
  507. //
  508. ////////////////////////////////////////////////////////////////////
  509. void drawchar(int x,int y,int chr)
  510. {
  511.  switch(videomode)
  512.  {
  513.   case CGA: CGAcharout(x,y,chr); break;
  514.   case EGA1:
  515.   case EGA2: EGAcharout(x,y,chr,videomode); break;
  516.   case VGA: VGAcharout(x,y,chr);
  517.  }
  518. }
  519.  
  520. ////////////////////////////////////////////////////////////////////
  521. //
  522. // Set a video mode
  523. //
  524. ////////////////////////////////////////////////////////////////////
  525. void setvideo(video vid)
  526. {
  527.  //
  528.  // create CGA font (if not already created)
  529.  //
  530.  if (vid==CGA && !CGAfont)
  531.    {
  532.     unsigned char huge *oldfont=MK_FP(FP_SEG(&TEDCHAR),FP_OFF(&TEDCHAR));
  533.     unsigned i,j,huge *newfont;
  534.  
  535.     centerwindow(20,1);
  536.     print("Creating CGA font...");
  537.  
  538.     MMAllocate(&CGAfont,2048);
  539.     newfont=MK_FP(CGAfont,0);
  540.  
  541.     for(i=0;i<127;i++)
  542.       for(j=0;j<8;j++)
  543.     (unsigned)*(newfont+i*8+j)=doubled[*(oldfont+i*8+j)]; //color=|0xaaaa;
  544.    }
  545.  else
  546.  //
  547.  // OR create VGA font (if not already created)
  548.  //
  549.  if (vid==VGA && !VGAfont)
  550.    {
  551.     unsigned char huge *oldfont=MK_FP(FP_SEG(&TEDCHAR),FP_OFF(&TEDCHAR)),
  552.     huge *newfont;
  553.     unsigned i,j,k;
  554.     unsigned char bitbyte[2]={0,0xff}; // colors={0x7e,0x78};
  555.  
  556.     centerwindow(20,1);
  557.     print("Creating VGA font...");
  558.  
  559.     MMAllocate(&VGAfont,0x2000);
  560.     newfont=MK_FP(VGAfont,0);
  561.  
  562.     for(i=0;i<128;i++)
  563.       for(j=0;j<8;j++)
  564.     for(k=0;k<8;k++)
  565.       *(newfont+i*64+j*8+k)=bitbyte[(*(oldfont+i*8+j)>>(7-k))&1];
  566.    }
  567.  //
  568.  // Now, change video modes!
  569.  //
  570.  switch(vid)
  571.  {
  572.   case TEXT: _AX=3; break;
  573.   case CGA:
  574.     screencenterx=19;
  575.     screencentery=11;
  576.     scrnbot=199;
  577.     scrnrgt=319;
  578.     _AX=4;
  579.     break;
  580.   case EGA1:
  581.     screencenterx=19;
  582.     screencentery=11;
  583.     scrnbot=199;
  584.     scrnrgt=319;
  585.     _AX=0x0d;
  586.     break;
  587.   case EGA2:
  588.     screencenterx=39;
  589.     screencentery=29;
  590.     scrnbot=479;
  591.     scrnrgt=638;
  592.     _AX=0x12;
  593.     break;
  594.   case VGA:
  595.     _AX=0x13;
  596.     screencenterx=19;
  597.     screencentery=11;
  598.     scrnbot=199;
  599.     scrnrgt=319;
  600.  }
  601.  geninterrupt(0x10);
  602.  videomode=vid;
  603.  
  604.  //
  605.  // Set CGA mouse cursor (normal one sucks)
  606.  //
  607.  if (vid==CGA)
  608.    {
  609.     static unsigned CGAcursor[]=
  610.       {
  611.        0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03,
  612.        0xff03,0xffff,0xffff,0xffff,0xffff,0xffff,
  613.  
  614.        0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c,
  615.        0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000
  616.       };
  617.  
  618.     _BX=0;
  619.     _CX=0;
  620.     _DX=FP_OFF(CGAcursor);
  621.     _ES=_DS;
  622.     _AX=9;
  623.     geninterrupt(0x33);
  624.    }
  625.  else
  626.  //
  627.  // Move EGA font into LATCH memory!
  628.  //
  629.  if (vid==EGA1 || vid==EGA2)
  630.    {
  631.     unsigned i,s=FP_SEG(&TEDCHAR),o=FP_OFF(&TEDCHAR);
  632.  
  633.     outport(GCindex,GCmode);
  634.     for (i=0;i<4;i++)
  635.       {
  636.        outport(SCindex,SCmapmask | (1<<i)*256);
  637.        movedata(s,o+i*0x400,0xaf00,0,0x400);
  638.       }
  639.    }
  640.  else
  641.  //
  642.  // OR set the VGA palette
  643.  //
  644.  if (vid==VGA)    // set VGA palette
  645.    {
  646.     _BX=0;
  647.     _CX=0x100;
  648.     _DX=FP_OFF(&VGAPAL);
  649.     _ES=FP_SEG(&VGAPAL);
  650.     _AX=0x1012;
  651.     geninterrupt(0x10);
  652.    }
  653. }
  654.  
  655.  
  656. ////////////////////////////////////////////////////////////////////
  657. //
  658. // Quit the fuck outta here!
  659. //
  660. ////////////////////////////////////////////////////////////////////
  661. void Quit(char *string)
  662. {
  663.  Unhook();
  664.  setvideo(TEXT);
  665.  poke(0,0x41a,peek(0,0x41c));    // clear keyboard
  666.  if (string[0])
  667.    {
  668.     printf("TED5 ERROR: %s",string);
  669.     exit(1);
  670.    }
  671.  printf("Thanks for using TED5!");
  672.  nosound();
  673.  exit(0);
  674. }
  675.  
  676.  
  677. //////////////////////////
  678. //
  679. // drawwindow
  680. // draws a bordered window and homes the cursor
  681. //
  682. //////////////////////////
  683.  
  684. void drawwindow (int xl, int yl, int xh, int yh)
  685. {
  686.  int x,y;
  687.  win_xl=xl;
  688.  win_yl=yl;
  689.  win_xh=xh;
  690.  win_yh=yh;        // so the window can be erased
  691.  
  692.  drawchar (xl,yl,1);
  693.  for (x=xl+1;x<xh;x++)
  694.    drawchar (x,yl,2);
  695.  drawchar (xh,yl,3);
  696.  for (y=yl+1;y<yh;y++)
  697.  {
  698.    drawchar (xl,y,4);
  699.    for (x=xl+1;x<xh;x++)
  700.      drawchar (x,y,' ');
  701.    drawchar (xh,y,5);
  702.  }
  703.  drawchar (xl,yh,6);
  704.  for (x=xl+1;x<xh;x++)
  705.    drawchar (x,yh,7);
  706.  drawchar (xh,yh,8);
  707.  
  708.  sx = leftedge = xl+1;
  709.  sy = yl+1;
  710. }
  711.  
  712. ////////////////////////////
  713. //
  714. // erasewindow
  715. // clears out the last window and it's border to spaces
  716. //
  717. ///////////////////////////
  718.  
  719. void erasewindow (void)
  720. {
  721.   bar (win_xl,win_yl,win_xh,win_yh,' ');
  722. }
  723.  
  724. /////////////////////////////
  725. //
  726. // centerwindow
  727. // Centers a drawwindow of the given size
  728. //
  729. /////////////////////////////
  730.  
  731. void centerwindow (int width, int height)
  732. {
  733.   int xl = screencenterx-width/2;
  734.   int yl = screencentery-height/2;
  735.  
  736.   drawwindow (xl,yl,xl+width+1,yl+height+1);
  737. }
  738.  
  739. ///////////////////////////////
  740. //
  741. // expwin {h / v}
  742. // Grows the window outward
  743. //
  744. ///////////////////////////////
  745. void expwinh (int width, int height)
  746. {
  747.   if (width > 2)
  748.     expwinh (width-2,height);
  749.  
  750.   WaitVBL (1);
  751.   centerwindow (width,height);
  752. }
  753.  
  754. void expwinv (int width, int height)
  755. {
  756.   if (height >2)
  757.     expwinv (width,height-2);
  758.  
  759.   WaitVBL (1);
  760.   centerwindow (width,height);
  761. }
  762. void expwin (int width, int height)
  763. {
  764.   if (width > 2)
  765.   {
  766.     if (height >2)
  767.       expwin (width-2,height-2);
  768.     else
  769.       expwinh (width-2,height);
  770.   }
  771.   else
  772.     if (height >2)
  773.       expwinv (width,height-2);
  774.  
  775.   WaitVBL (1);
  776.   centerwindow (width,height);
  777. }
  778.  
  779.  
  780. ////////////////////////////////////////////////////////////
  781. //
  782. // Save a *LARGE* file from a FAR buffer!
  783. // by John Romero (C) 1990 Gamer's Edge
  784. //
  785. ////////////////////////////////////////////////////////////
  786. void SaveFile(char *filename,char huge *buffer,long offset,long size)
  787. {
  788.  unsigned int handle,buf1,buf2,offlo,offhi,sizelo,sizehi;
  789.  
  790.  buf1=FP_OFF(buffer);
  791.  buf2=FP_SEG(buffer);
  792.  offlo=offset&0xffff;
  793.  offhi=offset>>16;
  794.  sizelo=size&0xffff;
  795.  sizehi=size>>16;
  796.  
  797. asm        mov    ax,offlo
  798. asm        or    ax,offhi
  799. asm        jz    CREATEIT
  800.  
  801. asm        mov    dx,filename
  802. asm        mov    ax,3d02h        // OPEN w/handle (read only)
  803. asm        int    21h
  804. asm        jnc    L0
  805.  
  806.  return;
  807.  
  808. L0:
  809.  
  810. asm        mov    handle,ax
  811.  
  812. asm        mov    bx,handle
  813. asm        mov     dx,offlo
  814. asm        mov    cx,offhi
  815. asm        mov    ax,4200h
  816. asm        int    21h            // SEEK (to file offset)
  817. asm        jc    out
  818.  
  819. asm        jmp    DOSAVE
  820.  
  821. CREATEIT:
  822.  
  823. asm        mov    dx,filename
  824. asm        mov    ax,3c00h        // CREATE w/handle (read only)
  825. asm        xor    cx,cx
  826. asm        int    21h
  827. asm        jc    out
  828.  
  829. asm        mov    handle,ax
  830.  
  831. DOSAVE:
  832.  
  833. asm        cmp    WORD PTR sizehi,0        // larger than 1 segment?
  834. asm        je    L2
  835.  
  836. L1:
  837.  
  838. asm        push    ds
  839. asm        mov    bx,handle
  840. asm        mov    cx,8000h
  841. asm        mov    dx,buf1
  842. asm        mov    ax,buf2
  843. asm        mov    ds,ax
  844. asm        mov    ah,40h            // WRITE w/handle
  845. asm        int    21h
  846. asm        pop    ds
  847.  
  848. asm        add    WORD PTR buf2,800h        // bump ptr up 1/2 segment
  849. asm        sub    WORD PTR sizelo,8000h        // done yet?
  850. asm        sbb    WORD PTR sizehi,0
  851. asm        cmp    WORD PTR sizehi,0
  852. asm        ja    L1
  853. asm        cmp    WORD PTR sizelo,8000h
  854. asm        jae    L1
  855.  
  856. L2:
  857.  
  858. asm        push    ds
  859. asm        mov    bx,handle
  860. asm        mov    cx,sizelo
  861. asm        mov    dx,buf1
  862. asm        mov    ax,buf2
  863. asm        mov    ds,ax
  864. asm        mov    ah,40h            // WRITE w/handle
  865. asm        int    21h
  866. asm        pop    ds
  867.  
  868. out:
  869.  
  870. asm        mov    bx,handle        // CLOSE w/handle
  871. asm        mov    ah,3eh
  872. asm        int    21h
  873.  
  874. }
  875.  
  876. ////////////////////////////////////////////////////////////
  877. //
  878. // Load a *LARGE* file into a FAR buffer!
  879. // by John Romero (C) 1990 Gamer's Edge
  880. //
  881. ////////////////////////////////////////////////////////////
  882. unsigned long LoadFile(char *filename,char huge *buffer,long offset,long size)
  883. {
  884.  unsigned handle,flength1=0,flength2=0,buf1,buf2,len1,len2,
  885.       rsize1,rsize2,roffset1,roffset2;
  886.  
  887.  rsize1=size&0xffff;
  888.  rsize2=size>>16;
  889.  roffset1=offset&0xffff;
  890.  roffset2=offset>>16;
  891.  buf1=FP_OFF(buffer);
  892.  buf2=FP_SEG(buffer);
  893.  
  894. asm        mov    dx,filename
  895. asm        mov    ax,3d00h        // OPEN w/handle (read only)
  896. asm        int    21h
  897. asm        jnc    L_0
  898.  
  899.  return 0;
  900.  
  901. L_0:
  902.  
  903. asm        mov    handle,ax
  904. asm        mov    bx,ax
  905. asm        xor    cx,cx
  906. asm        xor    dx,dx
  907. asm        mov    ax,4202h
  908. asm        int    21h            // SEEK (find file length)
  909. asm        jc    out
  910.  
  911. asm        mov    flength1,ax
  912. asm        mov    len1,ax
  913. asm        mov    flength2,dx
  914. asm        mov    len2,dx
  915.  
  916. asm        mov    ax,rsize1        // was a size specified?
  917. asm        or    ax,rsize1
  918. asm        jz    LOADALL
  919.  
  920. asm        mov    ax,rsize1        // only load size requested
  921. asm        mov    len1,ax
  922. asm        mov    ax,rsize2
  923. asm        mov    len2,ax
  924.  
  925. LOADALL:
  926.  
  927. asm        mov    bx,handle
  928. asm        mov     dx,roffset1
  929. asm        mov    cx,roffset2
  930. asm        mov    ax,4200h
  931. asm        int    21h            // SEEK (to file offset)
  932. asm        jc    out
  933.  
  934. asm        cmp    WORD PTR len2,0            // MULTI-SEGMENTAL?
  935. asm        je      L_2
  936.  
  937. L_1:
  938.  
  939. asm        push    ds
  940. asm        mov    bx,handle
  941. asm        mov    cx,8000h        // read 32K chunks
  942. asm        mov    dx,buf1
  943. asm        mov    ax,buf2
  944. asm        mov    ds,ax
  945. asm        mov    ah,3fh            // READ w/handle
  946. asm        int    21h
  947. asm        pop    ds
  948. asm        jc    out
  949.  
  950. asm        add    WORD PTR buf2,800h
  951. asm        sub    WORD PTR len1,8000h
  952. asm        sbb    WORD PTR len2,0
  953. asm        cmp    WORD PTR len2,0
  954. asm        ja    L_1
  955. asm        cmp    WORD PTR len1,8000h
  956. asm        jae    L_1
  957.  
  958. L_2:
  959.  
  960. asm        push    ds
  961. asm        mov    bx,handle
  962. asm        mov    cx,len1
  963. asm        mov    dx,buf1
  964. asm        mov    ax,buf2
  965. asm        mov    ds,ax
  966. asm        mov    ah,3fh            // READ w/handle
  967. asm        int    21h
  968. asm        pop    ds
  969. asm        jmp    exit
  970.  
  971. out:
  972.  
  973. asm        mov    WORD PTR flength2,0
  974. asm        mov    WORD PTR flength1,0
  975.  
  976. exit:
  977.  
  978. asm        mov    bx,handle        // CLOSE w/handle
  979. asm        mov    ah,3eh
  980. asm        int    21h
  981.  
  982.  return (flength2*0x10000+flength1);
  983.  
  984. }
  985.  
  986.  
  987. ////////////////////////////////////////////////////////////
  988. //
  989. // Allocate memory and load file in
  990. //
  991. ////////////////////////////////////////////////////////////
  992. void LoadIn(char *filename,void _seg **baseptr)
  993. {
  994.  char errstr[80];
  995.  int handle;
  996.  long len;
  997.  
  998.  if ((handle=open(filename,O_BINARY))==-1)
  999.    {
  1000.     strcpy(errstr,"Error loading file ");
  1001.     strcat(errstr,filename);
  1002.     Quit(errstr);
  1003.    }
  1004.  
  1005.  len=filelength(handle);
  1006.  close(handle);
  1007.  MMAllocate((memptr *)baseptr,len);
  1008.  LoadFile(filename,MK_FP(*baseptr,0),0,0);
  1009. }
  1010.  
  1011.  
  1012.